package com.yckj.ytracker.api.trace;

import com.yckj.ytracker.api.config.Global;
import com.yckj.ytracker.api.model.Span;
import com.yckj.ytracker.api.util.TrackerHelper;

import java.util.LinkedList;

/**
 * @author liuwei
 * @version 2017/10/16 上午11:56
 * @description 搜集器上下文
 * @see
 * @since 1.0
 */
public class TraceContext {

    private static final ThreadLocal<LinkedList<Span>> currentSpan = new ThreadLocal<>();
    private static final ThreadLocal<Span> parentSpan = new ThreadLocal<>();

    public TraceContext() {
        currentSpan.set(new LinkedList<>());
    }

    public Span getParentSpan() {
        return parentSpan.get();
    }

    public void setParentSpan(Span span) {
        parentSpan.set(span);
    }

    public Span getCurrentSpan() {
        LinkedList<Span> spanList = currentSpan.get();
        if (spanList == null || spanList.isEmpty()) {
            return null;
        }
        return spanList.getLast();
    }

    public void setCurrentSpan(Span span) {
        LinkedList<Span> spanList = currentSpan.get();
        if (spanList == null || spanList.isEmpty()) {
            spanList = new LinkedList<>();
            currentSpan.set(spanList);
        }
        int size = spanList.size();
        if (span != null) {
            int limit = Global.getInstance().getLimit();
            if (size >= limit) {
                int more = size - limit;
                while (more-- > 0) {
                    TrackerHelper.getSpanCollector().collect(spanList.getFirst());
                    spanList.removeFirst();
                }
            }
            spanList.addLast(span);
        } else {
            if (size > 0) {
                spanList.removeLast();
            }
        }
    }

    public void refresh() {
        Span span = null;
        while ((span = getCurrentSpan()) != null) {
            TrackerHelper.getSpanCollector().collect(span);
            setCurrentSpan(null);
        }
        currentSpan.set(new LinkedList<>());
        parentSpan.set(null);
    }

}
